<template>
  <mt-dzr
    :id="item.id"
    v-for="(item, index) in renderCoreProps.doneJson"
    :key="item.id"
    v-model="item.binfo"
    :scale-ratio="renderCoreProps.canvasCfg.scale"
    :grid="renderCoreProps.gridCfg"
    :resize="item.resize"
    :rotate="item.rotate"
    :lock="renderCoreProps.globalLock ? true : item.lock"
    :active="renderCoreProps.preivewMode ? false : item.active"
    :useProportionalScaling="item.use_proportional_scaling"
    :forceFreeDragging="item.type === 'server-svg'"
    :show-ghost-dom="renderCoreProps.showGhostDom"
    :hide="item.hide"
    :disabled="renderCoreProps.preivewMode"
    :adsorp_diff="globalStore.adsorp_diff"
    @mousedown="onMouseDown(item, $event)"
    @update:model-value="onUpdateModelValue(item.id, $event)"
    @on-item-move="(e: any) => onItemMove(e, item.id)"
    @move-mouse-up="onMoveMouseUp()"
    @on-mouse-enter="onMouseEnter($event, item)"
    @on-mouse-leave="onMouseLeave($event, item)"
    @on-resize-move="onResizeMove($event)"
    @on-resize-done="onResizeDone(item)"
    @on-rotate-move="onRotateMove($event)"
    @on-rotate-done="onRotateDone(item)"
    @on-right-click="onRightClick($event, item)"
    :class="`${item.type == 'sys-line' ? 'pointer-events-none' : ''} ${getCommonAni(
      item
    )} cursor-pointer`"
  >
    <el-popover
      v-if="renderCoreProps.preivewMode && renderCoreProps.showPopover"
      placement="top-start"
      title="属性信息"
      :width="200"
      trigger="hover"
    >
      <template #reference>
        <render-item
          :item-json="item"
          :canvas-cfg="renderCoreProps.canvasCfg"
          :canvas-dom="renderCoreProps.canvasDom"
          :grid="renderCoreProps.gridCfg"
          :done-json="renderCoreProps.doneJson"
          :lock-state="renderCoreProps.globalLock ? true : item.lock"
          :line-append-enable="renderCoreProps.lineAppendEnable"
          :preview-mode="renderCoreProps.preivewMode"
          @update:item-json="onUpdateItemJson(index, $event)"
          @set-intention="(val) => renderCoreEmits('setIntention', val)"
          @line-mouse-up="onLineMouseUp"
          v-on="renderCoreProps.preivewMode ? eventToVOn(item) : {}"
        ></render-item>
      </template>
      <template #default>
        <div v-for="(prop_item, prop_item_key) in item.props" :key="prop_item_key">
          <div v-if="!prop_item.disabled">{{ prop_item.title }}:{{ prop_item.val }}</div>
        </div>
      </template>
    </el-popover>
    <render-item
      v-else
      :item-json="item"
      :canvas-cfg="renderCoreProps.canvasCfg"
      :canvas-dom="renderCoreProps.canvasDom"
      :grid="renderCoreProps.gridCfg"
      :done-json="renderCoreProps.doneJson"
      :lock-state="renderCoreProps.globalLock ? true : item.lock"
      :line-append-enable="renderCoreProps.lineAppendEnable"
      :preview-mode="renderCoreProps.preivewMode"
      @update:item-json="onUpdateItemJson(index, $event)"
      @set-intention="(val) => renderCoreEmits('setIntention', val)"
      @line-mouse-up="onLineMouseUp"
      v-on="renderCoreProps.preivewMode ? eventToVOn(item) : {}"
    ></render-item>
  </mt-dzr>
</template>
<script setup lang="ts">
import { nextTick, reactive, ref, watch, onMounted, onBeforeUpdate, onUpdated } from 'vue';
import MtDzr from '@/components/mt-dzr/index.vue';
import RenderItem from '@/components/mt-edit/components/render-item/index.vue';
import type {
  IDoneJson,
  IDoneJsonBinfo,
  IGlobalStoreCanvasCfg,
  IGlobalStoreGridCfg
} from '@/components/mt-edit/store/types';
import type { MouseTouchEvent } from '../types';
import { globalStore } from '../../store/global';
import type { onItemMoveParams } from './types';
import { eventToVOn } from '../../utils';
import { cacheStore } from '../../store/cache';
import { getCurrentInstance } from 'vue';
import TextVue from '@/components/custom-components/text-vue/index.vue';
import CardVue from '@/components/custom-components/card-vue/index.vue';
import NowTimeVue from '@/components/custom-components/now-time-vue/index.vue';
import KvVue from '@/components/custom-components/kv-vue/index.vue';
import SysButtonVue from '@/components/custom-components/sys-button-vue/index.vue';
import { startComponentRender, endComponentRender } from '@/utils/performance-monitor';
import ElTableVue from '@/components/custom-components/el-table-vue/index.vue';
import ElProgressVue from '@/components/custom-components/el-progress-vue/index.vue';
import ElButtonVue from '@/components/custom-components/el-button-vue/index.vue';
import ElTextVue from '@/components/custom-components/el-text-vue/index.vue';
import ElSwitchVue from '@/components/custom-components/el-switch-vue/index.vue';
import ElCalendarVue from '@/components/custom-components/el-calendar-vue/index.vue';
import ElTagVue from '@/components/custom-components/el-tag-vue/index.vue';
import ElTimelineVue from '@/components/custom-components/el-timeline-vue/index.vue';
import ElStatisticVue from '@/components/custom-components/el-statistic-vue/index.vue';
import ElSegmentedVue from '@/components/custom-components/el-segmented-vue/index.vue';
import ElStepsVue from '@/components/custom-components/el-steps-vue/index.vue';
import ElDividerVue from '@/components/custom-components/el-divider-vue/index.vue';
import ElDescriptionsVue from '@/components/custom-components/el-descriptions-vue/index.vue';
import ElImageVue from '@/components/custom-components/el-image-vue/index.vue';
import ElCarouselVue from '@/components/custom-components/el-carousel-vue/index.vue';
import ElAvatarVue from '@/components/custom-components/el-avatar-vue/index.vue';
import ElIframeVue from '@/components/custom-components/el-iframe-vue/index.vue';
import ElVideoVue from '@/components/custom-components/el-video-vue/index.vue';
import EchartLineVue from '@/components/custom-components/echart-line-vue/index.vue';
import EchartCurveVue from '@/components/custom-components/echart-curve-vue/index.vue';
import EchartPieVue from '@/components/custom-components/echart-pie-vue/index.vue';
import EchartBarVue from '@/components/custom-components/echart-bar-vue/index.vue';
import EchartHorizontalBarVue from '@/components/custom-components/echart-horizontal-bar-vue/index.vue';
import EchartUniversalVue from '@/components/custom-components/echart-universal-vue/index.vue';
import GaugeDashboardVue from '@/components/custom-components/gauge-dashboard-vue/index.vue';
import GaugeSimpleVue from '@/components/custom-components/gauge-simple-vue/index.vue';
import GaugeAbilityVue from '@/components/custom-components/gauge-ability-vue/index.vue';
import GaugeCompletionVue from '@/components/custom-components/gauge-completion-vue/index.vue';
import GaugeTowerVue from '@/components/custom-components/gauge-tower-vue/index.vue';
import GaugeCpuVue from '@/components/custom-components/gauge-cpu-vue/index.vue';
import GaugeCleanVue from '@/components/custom-components/gauge-clean-vue/index.vue';
import GaugeProgressVue from '@/components/custom-components/gauge-progress-vue/index.vue';
import GaugeThickVue from '@/components/custom-components/gauge-thick-vue/index.vue';
import GaugeColorfulVue from '@/components/custom-components/gauge-colorful-vue/index.vue';
import GaugeTemperatureVue from '@/components/custom-components/gauge-temperature-vue/index.vue';
import GaugeDoubleVue from '@/components/custom-components/gauge-double-vue/index.vue';
import LiquidFillVue from '@/components/custom-components/liquid-fill-vue/index.vue';
import { ElPopover } from 'element-plus';
import { useAutoDataBinding, useDataBinding } from '@/composables/use-data-binding';
const instance = getCurrentInstance();
const now_include_keys = Object.keys(instance?.appContext?.components as any);
if (!now_include_keys.includes('text-vue')) {
  instance?.appContext.app.component('text-vue', TextVue);
}
if (!now_include_keys.includes('card-vue')) {
  instance?.appContext.app.component('card-vue', CardVue);
}
if (!now_include_keys.includes('now-time-vue')) {
  instance?.appContext.app.component('now-time-vue', NowTimeVue);
}
if (!now_include_keys.includes('kv-vue')) {
  instance?.appContext.app.component('kv-vue', KvVue);
}
if (!now_include_keys.includes('sys-button-vue')) {
  instance?.appContext.app.component('sys-button-vue', SysButtonVue);
}
if (!now_include_keys.includes('el-table-vue')) {
  instance?.appContext.app.component('el-table-vue', ElTableVue);
}
if (!now_include_keys.includes('el-progress-vue')) {
  instance?.appContext.app.component('el-progress-vue', ElProgressVue);
}
if (!now_include_keys.includes('el-button-vue')) {
  instance?.appContext.app.component('el-button-vue', ElButtonVue);
}
if (!now_include_keys.includes('el-text-vue')) {
  instance?.appContext.app.component('el-text-vue', ElTextVue);
}
if (!now_include_keys.includes('el-switch-vue')) {
  instance?.appContext.app.component('el-switch-vue', ElSwitchVue);
}
if (!now_include_keys.includes('el-calendar-vue')) {
  instance?.appContext.app.component('el-calendar-vue', ElCalendarVue);
}
if (!now_include_keys.includes('el-tag-vue')) {
  instance?.appContext.app.component('el-tag-vue', ElTagVue);
}
if (!now_include_keys.includes('el-timeline-vue')) {
  instance?.appContext.app.component('el-timeline-vue', ElTimelineVue);
}
if (!now_include_keys.includes('el-statistic-vue')) {
  instance?.appContext.app.component('el-statistic-vue', ElStatisticVue);
}
if (!now_include_keys.includes('el-segmented-vue')) {
  instance?.appContext.app.component('el-segmented-vue', ElSegmentedVue);
}
if (!now_include_keys.includes('el-steps-vue')) {
  instance?.appContext.app.component('el-steps-vue', ElStepsVue);
}
if (!now_include_keys.includes('el-divider-vue')) {
  instance?.appContext.app.component('el-divider-vue', ElDividerVue);
}
if (!now_include_keys.includes('el-descriptions-vue')) {
  instance?.appContext.app.component('el-descriptions-vue', ElDescriptionsVue);
}
if (!now_include_keys.includes('el-image-vue')) {
  instance?.appContext.app.component('el-image-vue', ElImageVue);
}
if (!now_include_keys.includes('el-carousel-vue')) {
  instance?.appContext.app.component('el-carousel-vue', ElCarouselVue);
}
if (!now_include_keys.includes('el-avatar-vue')) {
  instance?.appContext.app.component('el-avatar-vue', ElAvatarVue);
}
if (!now_include_keys.includes('el-iframe-vue')) {
  instance?.appContext.app.component('el-iframe-vue', ElIframeVue);
}
if (!now_include_keys.includes('el-video-vue')) {
  instance?.appContext.app.component('el-video-vue', ElVideoVue);
}
if (!now_include_keys.includes('echart-line')) {
  instance?.appContext.app.component('echart-line', EchartLineVue);
}
if (!now_include_keys.includes('echart-curve')) {
  instance?.appContext.app.component('echart-curve', EchartCurveVue);
}
if (!now_include_keys.includes('echart-pie')) {
  instance?.appContext.app.component('echart-pie', EchartPieVue);
}
if (!now_include_keys.includes('echart-bar')) {
  instance?.appContext.app.component('echart-bar', EchartBarVue);
}
if (!now_include_keys.includes('echart-horizontal-bar')) {
  instance?.appContext.app.component('echart-horizontal-bar', EchartHorizontalBarVue);
}
if (!now_include_keys.includes('echart-universal-vue')) {
  instance?.appContext.app.component('echart-universal-vue', EchartUniversalVue);
}

// 同时注册为echart-universal（可能的别名问题）
if (!now_include_keys.includes('echart-universal')) {
  instance?.appContext.app.component('echart-universal', EchartUniversalVue);
}

// 注册仪表盘组件
if (!now_include_keys.includes('gauge-dashboard-vue')) {
  instance?.appContext.app.component('gauge-dashboard-vue', GaugeDashboardVue);
}

// 注册简单仪表盘组件
if (!now_include_keys.includes('gauge-simple-vue')) {
  instance?.appContext.app.component('gauge-simple-vue', GaugeSimpleVue);
}

// 注册能力值仪表盘组件
if (!now_include_keys.includes('gauge-ability-vue')) {
  instance?.appContext.app.component('gauge-ability-vue', GaugeAbilityVue);
}

// 注册完成率仪表盘组件
if (!now_include_keys.includes('gauge-completion-vue')) {
  instance?.appContext.app.component('gauge-completion-vue', GaugeCompletionVue);
}

// 注册塔米分仪表盘组件
if (!now_include_keys.includes('gauge-tower-vue')) {
  instance?.appContext.app.component('gauge-tower-vue', GaugeTowerVue);
}

// 注册CPU利用率仪表盘组件
if (!now_include_keys.includes('gauge-cpu-vue')) {
  instance?.appContext.app.component('gauge-cpu-vue', GaugeCpuVue);
}

// 注册简洁蓝色仪表盘组件
if (!now_include_keys.includes('gauge-clean-vue')) {
  instance?.appContext.app.component('gauge-clean-vue', GaugeCleanVue);
}

// 注册进度条仪表盘组件
if (!now_include_keys.includes('gauge-progress-vue')) {
  instance?.appContext.app.component('gauge-progress-vue', GaugeProgressVue);
}

// 注册宽进度条仪表盘组件
if (!now_include_keys.includes('gauge-thick-vue')) {
  instance?.appContext.app.component('gauge-thick-vue', GaugeThickVue);
}

// 注册多色轴线仪表盘组件
if (!now_include_keys.includes('gauge-colorful-vue')) {
  instance?.appContext.app.component('gauge-colorful-vue', GaugeColorfulVue);
}

// 注册双层温度仪表盘组件
if (!now_include_keys.includes('gauge-temperature-vue')) {
  instance?.appContext.app.component('gauge-temperature-vue', GaugeTemperatureVue);
}

// 注册双圈切换仪表盘组件
if (!now_include_keys.includes('gauge-double-vue')) {
  instance?.appContext.app.component('gauge-double-vue', GaugeDoubleVue);
}
// 注册液体填充图组件
if (!now_include_keys.includes('liquid-fill-vue')) {
  instance?.appContext.app.component('liquid-fill-vue', LiquidFillVue);
}

type RenderCoreProps = {
  doneJson: IDoneJson[];
  canvasCfg: IGlobalStoreCanvasCfg;
  gridCfg: IGlobalStoreGridCfg;
  showGhostDom: boolean;
  canvasDom: HTMLElement | null;
  globalLock: boolean;
  preivewMode?: boolean;
  lineAppendEnable?: boolean;
  showPopover?: boolean;
};
const renderCoreProps = withDefaults(defineProps<RenderCoreProps>(), {
  doneJson: () => [],
  showGhostDom: true,
  preivewMode: false,
  lineAppendEnable: false,
  showPopover: true
});
const renderCoreEmits = defineEmits([
  'update:doneJson',
  'onMouseDown',
  'onItemMove',
  'onMoveMouseUp',
  'onItemMouseEnter',
  'onItemMouseLeave',
  'setIntention',
  'onItemResizeDone',
  'onItemRotateDone',
  'onItemRightClick'
]);
// 记录多选的情况除了本次移动组件其他的组件位置信息
const other_selected_items_binfo = ref<{ id: string; left: number; top: number }[]>([]);
const onMouseDown = (item: IDoneJson, e: MouseTouchEvent) => {
  other_selected_items_binfo.value = globalStore.done_json
    .filter((m) => m.id !== item.id)
    .map((m) => {
      return {
        id: m.id,
        left: m.binfo.left,
        top: m.binfo.top
      };
    });
  e.stopPropagation();
  renderCoreEmits('onMouseDown', item, e);
};
const onUpdateModelValue = (id: string, value: IDoneJsonBinfo) => {
  renderCoreEmits('update:doneJson', [
    ...renderCoreProps.doneJson.map((m) => {
      if (m.id === id) {
        return {
          ...m,
          binfo: value
        };
      }
      return m;
    })
  ]);
};
const onItemMove = (e: any, id: string) => {
  globalStore.setRealTimeData({
    show: true,
    text: `${e.new_lt.left},${e.new_lt.top}`
  });
  //如果同时选中多个组件，除去当前正在移动这个，手动更新其它的组件
  nextTick(() => {
    // 将所有移动组件的边界信息提供给父组件
    const item_move_params: onItemMoveParams = {
      //所有移动组件的信息
      move_item_bounding_info: globalStore.selected_items_id.map((m) => {
        const { left, top, width, height, right, bottom } = document
          .getElementById(m)!
          .getBoundingClientRect();
        return {
          id: m,
          type: globalStore.done_json.find((f) => f.id === m)!.type,
          left,
          top,
          width,
          height,
          right,
          bottom
        };
      }),
      //当前正在移动的组件的实时坐标信息
      move_binfo: e.move_binfo
    };
    if (globalStore.selected_items_id.length > 1) {
      // 找到其它的组件的id
      const other_items_id = globalStore.selected_items_id.filter((m) => m !== id);
      renderCoreEmits('update:doneJson', [
        ...renderCoreProps.doneJson.map((m) => {
          if (other_items_id.includes(m.id)) {
            //找到初始值
            const init_pos = other_selected_items_binfo.value.find((f) => f.id === m.id);
            return {
              ...m,
              binfo: {
                ...m.binfo,
                left: init_pos?.left + e.move_length.x,
                top: init_pos?.top + e.move_length.y
              }
            };
          }
          return m;
        })
      ]);
    }
    renderCoreEmits('onItemMove', item_move_params);
  });
};
const onMoveMouseUp = () => {
  renderCoreEmits('onMoveMouseUp');
  globalStore.setRealTimeData({
    show: false,
    text: ``
  });
};
const getCommonAni = (item: IDoneJson) => {
  if (!item.common_animations || !item.common_animations.val) {
    return ``;
  }
  return `animate__animated animate__${item.common_animations.val} animate__${item.common_animations.speed} animate__${item.common_animations.repeat} animate__${item.common_animations.delay}`;
};
const onUpdateItemJson = (index: number, item: IDoneJson) => {
  const temp_done_json = [...renderCoreProps.doneJson];
  temp_done_json[index] = item;
  renderCoreEmits('update:doneJson', temp_done_json);
};
const onMouseEnter = (e: MouseEvent, item: IDoneJson) => {
  renderCoreEmits('onItemMouseEnter', e, item);
};
const onMouseLeave = (e: MouseEvent, item: IDoneJson) => {
  renderCoreEmits('onItemMouseLeave', e, item);
};
const onResizeMove = (val: any) => {
  globalStore.setRealTimeData({
    show: true,
    text: `${val?.width}x${val?.height}`
  });
};
const onResizeDone = (item: IDoneJson) => {
  renderCoreEmits('onItemResizeDone', item);
  globalStore.setRealTimeData({
    show: false,
    text: ''
  });
};
const onRotateMove = (val: any) => {
  globalStore.setRealTimeData({
    show: true,
    text: `${val?.angle}°`
  });
};
const onRotateDone = (item: IDoneJson) => {
  globalStore.setRealTimeData({
    show: false,
    text: ``
  });
  renderCoreEmits('onItemRotateDone', item);
};
const onRightClick = (e: MouseEvent, item: IDoneJson) => {
  renderCoreEmits('onItemRightClick', e, item);
};
const onLineMouseUp = () => {
  setTimeout(() => {
    cacheStore.addHistory(globalStore.done_json);
  }, 1000);
};

// 数据绑定处理 - 只处理hide属性
const dataBindingInstances = ref<Map<string, any>>(new Map());

// 为有hide属性数据绑定的组件创建绑定实例
const setupHideBindings = () => {
  if (!renderCoreProps.preivewMode) {
    return; // 只在预览模式下启用数据绑定
  }

  renderCoreProps.doneJson.forEach((item, index) => {
    if (
      item.data_binding &&
      item.data_binding.enabled &&
      item.data_binding.targetProperty === 'hide'
    ) {
      const bindingKey = `${item.id}-hide`;

      // 如果已经存在绑定实例，先清理
      if (dataBindingInstances.value.has(bindingKey)) {
        const existingBinding = dataBindingInstances.value.get(bindingKey);
        if (existingBinding && existingBinding.unsubscribeFromData) {
          existingBinding.unsubscribeFromData();
        }
        dataBindingInstances.value.delete(bindingKey);
      }

      // 创建绑定实例
      const bindingInstance = useDataBinding({
        bindingConfig: item.data_binding,
        props: { hide: item.hide },
        onPropertyUpdate: (property: string, value: any) => {
          if (property === 'hide') {
            // 更新组件的hide属性
            const updatedItem = {
              ...item,
              hide: value
            };
            onUpdateItemJson(index, updatedItem);
          }
        },
        componentId: `render-core-${item.id}-hide`
      });

      // 启动数据绑定
      bindingInstance.subscribeToData();
      bindingInstance.updateData();

      dataBindingInstances.value.set(bindingKey, bindingInstance);
    }
  });
};

// 用于缓存上一次的监听值，避免无限循环
const lastWatchedValue = ref<string>('');

// 监听doneJson的结构变化（新增/删除组件），而不是属性值变化
watch(
  () => {
    const hideBindingItems = renderCoreProps.doneJson
      .filter((item) => item.data_binding?.enabled && item.data_binding.targetProperty === 'hide')
      .map((item) => `${item.id}:${item.data_binding?.dataPointId}:${item.data_binding?.enabled}`)
      .sort()
      .join('|');

    return `${renderCoreProps.doneJson.length}:${renderCoreProps.preivewMode}:${hideBindingItems}`;
  },
  (newValue) => {
    if (newValue === lastWatchedValue.value) {
      return;
    }

    lastWatchedValue.value = newValue;

    // 只清理render-core管理的绑定实例
    dataBindingInstances.value.forEach((binding) => {
      if (binding && binding.unsubscribeFromData) {
        binding.unsubscribeFromData();
      }
    });
    dataBindingInstances.value.clear();

    // 重新设置绑定
    setupHideBindings();
  },
  { immediate: true }
);

// 组件挂载时设置数据绑定
onMounted(() => {
  setupHideBindings();
  // 性能监控
  startComponentRender('render-core', 'RenderCore');
});

// 性能监控 - 更新开始时
onBeforeUpdate(() => {
  startComponentRender('render-core', 'RenderCore');
});

// 性能监控 - 更新结束时
onUpdated(() => {
  endComponentRender('render-core', 'RenderCore');
});
</script>
